from __future__ import generators
import os,random,sets,sys,socket,cStringIO,time
#from BitVector import BitVector
from pprint import pprint
import posnet_overlay_messages
import array,struct
import threading,thread
add_to_str = lambda o : "%s %s" % (o[0],o[1])

def set_reuse_addr (sock):
	""" from asyncore.py"""
	# try to re-use a server port if possible
	try:
		sock.setsockopt (
			socket.SOL_SOCKET, socket.SO_REUSEADDR,
			sock.getsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR) | 1
			)
	except:
		pass

from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \
     ENOTCONN, ESHUTDOWN, EINTR, EISCONN, errorcode

def connect_retry(mySocket,endpoint):
	attempts = 0
	err = None
	while attempts < 1:	
		attempts += 1 
		err = mySocket.connect_ex( endpoint )
		if err in (EINPROGRESS, EALREADY, EWOULDBLOCK):
			print >>sys.stderr,"socket error",(err, errorcode[err])
			#sys.stderr.flush()
			#time.sleep(5)
			continue 
		if err in (0, EISCONN): return
		else:
			raise socket.error, (err, errorcode[err])
	raise socket.error, (err, errorcode[err])

# tunnel 				
def connect_to_tunnel(host,port_number):
        mySocket = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
        connect_retry(mySocket,  (host,int(port_number)) )
	return mySocket	

def allocate_tunnel(port_number = None):
	""" return binding socket """
	timeout = 20
	if port_number is None: port_number = 0
	mySocket = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
	mySocket.settimeout(timeout)
        set_reuse_addr(mySocket)
        mySocket.bind ( ( "", int(port_number) ) )
        backlog_param = 1 # backlog param specifies number of queued connections : should be 1 or 5...
        mySocket.listen ( backlog_param )
	return mySocket

def tunnel_wait_for_establishment(mySocket):	
	""" return tunnel socket"""
	channel , sender = None, None
	try:
		channel, sender = mySocket.accept()
	except socket.timeout:
		raise
	mySocket.close()
	return channel	

def tunnel_recv_message(mySocket):
	msg  =recv_posnet_message_over_tcp_socket(mySocket,False)
	return msg

def tunnel_send_message(mySocket,msg):
	return send_posnet_message_over_tcp_socket(msg,mySocket,False)

#-------------------------------------------------------
# Send messages to a PosNET process waiting for answers
#-------------------------------------------------------
def send_answer_message( host,port_number,m,source = None):
    try:
        mySocket = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
        connect_retry(mySocket,  (host,int(port_number)) )
        if source is not None: m.source = source
        send_posnet_message_over_tcp_socket(m,mySocket,True)
        mySocket.close()
    except Exception,e:
        print >>sys.stderr,"Error: host=",host,port_number
        sys.stderr.flush()
        raise

def send_answer_end(host,port_number,source,query_id = None):
    mySocket = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
    target = (host,int(port_number))
    connect_retry(mySocket,  target )
    message = posnet_overlay_messages.posnet_finish_send_results(source,target,query_id)
    send_posnet_message_over_tcp_socket(message,mySocket,True)
    mySocket.close()

#---------------------------------------------------
# PosNET process to receive answers
#---------------------------------------------------
def recv_answers_prepare(port_number = None,timeout= None):
    """ receive answers on a socket listening for the specified port number
        @param port_number: used to listen to answers
        @param timeout: timeout before an error is raised
    """
    if timeout is not None: timeout = int(timeout)
    else: timeout = 30
    mySocket = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
    mySocket.settimeout(timeout)
    if port_number is None: port_number = 0
    port_number_integer = int(port_number)
    #mywaitinghostname = socket.INADDR_ANY
    mywaitinghostname = ""
    try:
        set_reuse_addr(mySocket)
        mySocket.bind ( ( mywaitinghostname, port_number_integer) )
        backlog_param = 5 # backlog param specifies number of queued connections : should be 1 or 5...
        mySocket.listen ( backlog_param )
        return mySocket
    except Exception,e:
        print >>sys.stderr,"Error while binding",( mywaitinghostname, port_number_integer),e
        raise
   

def recv_answers_iter_extract_next(msg):
	"""
		@param msg: message to handle
		returned 
			wait: waiting
	"""
	if msg is None: pass
	else:
		if hasattr(msg,"next"):
			for next in msg.next:
				oaddr = next[0]
				query_id = next[1]
				waddr = (oaddr,query_id)	
				yield waddr

	
 
def recv_answers_iter_wait(mySocket,waiting_channel= None,logger = None):
	 """ receive answers on a socket listening for the specified port number
		  @param mySocket: listening socket
		  @param waiting_channel: a set or a table of channels to wait
	 """
	 wait  = sets.Set()
	 if waiting_channel is not None:
		  for x in waiting_channel: wait.add(x)
	 ##### logger.info("---------------- begin work on"+str(mySocket.getsockname()))
	 while True:
		if False and logger is not None:
			logger.info("recv_answers_iter %s wait %s "% ( add_to_str(mySocket.getsockname()),str(' | '.join(["%s %s" % (x[1],add_to_str(x[0])) for x in wait]))))
		#-------
		channel , sender = None, None
		try: channel, sender = mySocket.accept()
		except socket.timeout: raise
		msg = recv_posnet_message_over_tcp_socket(channel,False)
		if msg is None: continue
		# treat next!
		for waddr in recv_answers_iter_extract_next(msg.data):
			wait.add(waddr)
		towait = msg.source
		if msg.message_type == posnet_overlay_messages.posnet_message_type_finish_send_results:
			# handle end
			 if msg.data is not None and msg.data != "": towait = (msg.source,msg.data)
			 if  towait in wait: wait.remove(towait)
			 if len(wait) == 0: break
		else:
			#handle result
			 if msg.message_type == posnet_overlay_messages.posnet_message_type_result:
				  towait = (msg.source,msg.data.query_id)
			 wait.add(towait)
			 yield sender,msg
        
#----------------------------------------------------------
posnet_tcp_server_quit_data =  "quit"
def send_posnet_message_over_tcp_socket(message,sock,shut  = None,buf_size = None):
	""" pack a posnet message and send it over the tcp socket
	    @param message: posnet message
	    @param sock: tcp socket used to transport the data
	    @param shut: if True, it will close the writing of this socket after message being sent
	    @param buf_size: size of chunks send with socket.sendall() function
	"""
	if shut is None: shut = True
	if buf_size is None: buf_size = 1024 *1024
	###tosend =  posnet_overlay_messages.pack_overlay_message( message )
	atosend =  posnet_overlay_messages.overlay_message_to_array( message )
	###max = len(tosend)
	max = atosend.buffer_info()[1] * atosend.itemsize
	#######print "send",max,"bytes from ",message.source,"->",message.target,"msg_type=",message.message_type
	sys.stdout.flush()
	sock.sendall( array.array("c",  struct.pack("I",  max )).tostring() ) 	
	###sock.sendall( posnet_overlay_messages.pack_bitstring( str( BitVector( intVal = int(len(tosend)) , size = 32 )) ) )	
	sock.sendall( atosend.tostring() )
	##### OLD version
	if False:	
		current = 0
		while current < len(tosend):
			end = current+buf_size
			if end > max: end = max
			sock.sendall( tosend[current:end] )
			current = end
		#if shut: sock.shutdown(socket.SHUT_WR)

def recv_posnet_message_over_tcp_socket(sock,shut = None,buf_size = None):
	""" receive a posnet message over the tcp socket
	    @param sock: tcp socket used to transport the data
	    @param shut: if True, it will close the reading of this socket after message being received
	    @param buf_size: size of chunks send with socket.recv() function
	"""
	# TODO with array
	raw_message = array.array("c")
	if shut is None: shut = True
	if buf_size is None: buf_size = 1024 
	sock.setblocking(1)
	try:
		mydat = ""
		if False:
			while len(mydat) < 4:
				mydat_r = sock.recv(4-len(mydat))
				if len(mydat_r) == 0:
					print "receive null!"
					sys.stdout.flush()
					continue
				else:
					mydat += mydatr
		mydat = sock.recv(4)
		sys.stdout.flush()
		datasize  = array.array("I", mydat).pop()	
		###datasize = int(posnet_overlay_messages.unpack_bits(mydat))
		if datasize == 0: return None # empty message !
		while len(raw_message) < datasize:
			wait_size = buf_size
			if wait_size > datasize-len(raw_message): wait_size = datasize-len(raw_message) 
			data = sock.recv(wait_size)
			#raw_message.extend( data )
			raw_message.fromstring( data )
			###raw_message += data       
		#if shut: sock.shutdown(socket.SHUT_RD)
		message = posnet_overlay_messages.array_to_overlay_message( raw_message )
		return message
	except:
		raise

def send_tcp_message(target,message, add_sock_name = None,wait_for_reply = None,logger = None,existing_socket =None,receive_socket=None):
	""" send a posnet message using tcp to a posnet overlay node
	    @param : (target_address, target_port) address and port of the posnet overlay node to contact, 
	    @param message: posnet message to send
	    @param add_sock_name: (default: False) if True, the posnet message will be modified before send: the source address and port is replaced in the posnet message.			
	    @param wait_for_reply: (default: False) if True, it will wait, after send the message, for a replied message
	    @param logger: 
	    @param receive_socket: socket prepared to send 
	    @param receive_socket: socket prepared to receive 
	"""
	target_address,target_port = target
	#----------
	# asyncrhon
	async = None
	if wait_for_reply:
		if message.answer_type == 0: async = False
		else: async = True	
	#-------------
	try:
		s = None
		if existing_socket is not None:
			#----------------
			s = existing_socket
		else: 
			#---- a soccket is allocated to receive
			s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			connect_retry(s,(target_address,target_port))	
		if (add_sock_name is not None and add_sock_name) or ( async is not None and async):
			message.source = s.getsockname()
		#---------------------------------
		my_receive_socket = None
		socket_port_number = None
		shut = None
		if message.answer_type != 0:
			shut = True
			if receive_socket is not None: my_receive_socket = receive_socket
			else:	# allocate receiving socket
				my_receive_socket =  recv_answers_prepare()
			socket_port_number = my_receive_socket.getsockname()[1]
			message.answer_type = socket_port_number
		#--------------------------------------------------
		send_posnet_message_over_tcp_socket(message,s,shut)
		ret = None
		#----------------------------
		# Wait 	
		if wait_for_reply is not None and wait_for_reply:
			if message.answer_type == 0:
				debug_socket_name = s.getsockname()
				try:
					ret = recv_posnet_message_over_tcp_socket(s)
				except:
					pass #no answer :)
			if existing_socket is None:
			# when the socket was already provided, we do not close it for future utilisation from caller
				s.close()
			#---
			if message.answer_type != 0:
				if receive_socket is not None:
					# receiving socket was provided
					# TODO ! (not implemented for the moment)
					raise Exception("not implemented")
					pass
				else:  
					# this is the current implementation	
					# of receiving results
					ret = []
					for sender,msg in recv_answers_iter_wait(my_receive_socket,None,logger):
						ret.append(msg)
						#if msg is not None: msg_str = msg.__class__.__name__
					my_receive_socket.close() 
					#TODOOOO
		else:
			if existing_socket is None: # when the socket was already provided, we do not close it for future utilisation from caller
				s.close()
		return ret
	except Exception, e:
		from traceback import print_exc
		print "Error in send_tcp_message(",target_address,target_port,")"
		print_exc()
		raise

def send_quit_tcp_message(target_address,target_port):
	""" send a tcp message to a posnet overlay node telling its tcp server loop to exit
	    WARNING: this id a dirty way to kill a posnet overlay node: USE IT FOR DEBUG ONLY  

	    @param target_address: address of the posnet overlay node to contact
	    @param target_port: port of the posnet node to contact
	"""
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	connect_retry(s,(target_address,target_port))	
	global posnet_tcp_server_quit_data
	s.sendall(posnet_tcp_server_quit_data)
	s.shutdown(socket.SHUT_WR)
	s.close()
	

def send_message(destination,msg,answer_type = None,logger =None,existing_socket = None):
    if answer_type is None: answer_type = 0
    msg.answer_type = answer_type
    if answer_type == 0:
        #####if logger is not None: logger.info("send_message: send message to "+str(destination))
        #####else: print "send_message: send message to",destination
        ack_message = send_tcp_message(destination,msg,True,True,logger,existing_socket)
        if ack_message is not None:
            #####if logger is not None: logger.info("send_message: answer received on "+str(ack_message.target)+" from "+str(ack_message.source)+ " : "+str(ack_message.__class__.__name__))
            #####else: print "send_message: answer received on",ack_message.target,"from",ack_message.source,":",ack_message.__class__.__name__
            return ack_message.data
        return None
    else:
        #####if logger is not None: logger.info("send_message -> send message to "+str(destination))
        #####else: print "send_message -> send message to",destination
        ack_messages = send_tcp_message(destination,msg,True,True,logger,existing_socket)
	myret = None
	if len(ack_messages) > 0:
		ack_message = ack_messages[0]
        	myret = ack_message.data
	#####if logger is not None: logger.info("send_message <- answer received from "+str(ack_message.target)+" from "+str(ack_message.source) + " : "+str(ack_message.__class__.__name__))
        #####else: print "send_message <- answer received from",ack_message.target,"from",ack_message.source,":",ack_message.__class__.__name__
        #print len( ack_message.data )/1024.0,"Kbytes of data from",ack_message.source
        return myret

def send_query_message(destination,msg,logger = None):
    msg.answer_type = -1
    ack_messages = send_tcp_message(destination,msg,True,True,logger)
    return ack_messages

#-----------------------------------------
# Implementation of client functions
#-----------------------------------------

def posnet_tunnel(destination,tunnel_addr,answer_type = None):
	""" send a posnet tunnel message to a posnet overlay node
	    @param destination: id of the destination, this may be (address,port)
	    @param tunnel_addr: address of tunnel
	    @param answer_type: type of answer 
	"""
	if answer_type is None: answer_type = 0
	m  = posnet_overlay_messages.posnet_tunnel_message( (None,None), destination ,tunnel_addr)
	print "send tunnel message to posnet overlay node %s"%str(destination)
	sys.stdout.flush() 
	return send_message(destination,m,answer_type)

def posnet_better_split(destination,answer_type = None):
	""" send a posnet ping message to a posnet overlay node
	    @param destination: id of the destination, this may be (address,port)
	    @param answer_type: type of answer 
	"""
	m  = posnet_overlay_messages.posnet_overlay_message( (None,None), destination ,posnet_overlay_messages.posnet_message_type_better_split)
	print >>sys.stderr,"send posnet better split to overlay node",destination
	sys.stdout.flush() 
	return send_message(destination,m,answer_type)



def posnet_ping(destination,answer_type = None):
	""" send a posnet ping message to a posnet overlay node
	    @param destination: id of the destination, this may be (address,port)
	    @param answer_type: type of answer 
	"""
	m  = posnet_overlay_messages.posnet_ping_message( (None,None), destination ,None)
	print >>sys.stderr,"ping posnet overlay node",destination
	sys.stdout.flush() 
	return send_message(destination,m,answer_type)

def posnet_draw(destination,other = None):
	""" send a posnet ping message to a posnet overlay node
	    @param destination: id of the destination, this may be (address,port)
	    @param other: optional to request other nodes	
	"""
	if other is None or not other: other = False
	else: other = True 	
	m  = posnet_overlay_messages.posnet_draw_message( (None,None), destination, other)
	#print >>sys.stderr,"draw posnet overlay node",destination
	#sys.stdout.flush()
	dot_data =  send_message(destination,m,0)
	#print len( dot_data )/1024.0,"Kbytes of dot data received"
	#sys.stdout.flush()
	return dot_data

def posnet_getparents_request(destination,space_points,answer_type = None):
	""" send a posnet getparents_request message to a posnet overlay node
	    @param destination: id of the destination, this may be (address,port)
	"""	
	m  = posnet_overlay_messages.posnet_getparents_request_message( (None,None), destination,space_points)
	#print "getparents_request to posnet overlay node",destination
	sys.stdout.flush()
	return send_message(destination,m,answer_type)
	#print "on socket",ack_message.target,",",len( ack_message.data ),"bytes of dot data answered from",ack_message.source


def posnet_graph_request(destination,answer_type = None):
	""" send a posnet graph_request message to a posnet overlay node
	    @param destination: id of the destination, this may be (address,port)
	"""	
	m  = posnet_overlay_messages.posnet_graph_request_message( (None,None), destination,None)
	print "graph_request to posnet overlay node",destination
	sys.stdout.flush()
	return send_message(destination,m,answer_type)
	#print "on socket",ack_message.target,",",len( ack_message.data ),"bytes of dot data answered from",ack_message.source

def posnet_state_request(destination,answer_type = None):
	""" send a posnet state_request message to a posnet overlay node
	    @param destination: id of the destination, this may be (address,port)
	"""	
	m  = posnet_overlay_messages.posnet_state_request_message( (None,None), destination,None)
	print "state_request to posnet overlay node",destination
	sys.stdout.flush()
	return send_message(destination,m,answer_type)


#---------------------------------------------------------------
def make_query(message_generator,logger = None):
		query_data = {'id':"", #fill here
					#'underlayPath':[], # deprecated
					#'overlayPath':[], #deprecated
					'dataHops':[], # each item is an entire hop; 1st hop = 1 peer, 2nd hop x peers, 3rd hop y peers...
					'dataPropag': [],
					'crossedPeers':sets.Set(),
					'crossedHosts':sets.Set(),
					#'messageNb':0,
					#'timeSpentAtPeers':{},
					'solutions':[]
				}
		query_data["legendHops"] = ["source","receive_time","propagation_time","process_time","process_iterations","process_jobs","n_results","n_next"]  	
		query_data["legendPropag"] = ["hop","iteration","source","source_query_id","receive_time","nextnode","next_query_id","n_entry_points"]  	
		propag_data = []
		iteration = 0
		query_to_hop = dict()	
		query_to_start_propag_time = dict()	
		data_hops = []
		for ack_msg in  message_generator:
			receive_time = time.clock()
			iteration += 1
			query_result_obj = ack_msg.data
			source = ack_msg.source
			query_id = str(query_result_obj.query_id)
			propagation_time = 0
			if len(query_to_hop) == 0:
				query_to_hop[query_id] = 0
				query_data["id"] = query_id
			else:
				propagation_time  = receive_time - query_to_start_propag_time[query_id]
			process_time = query_result_obj.data["time"]
			process_iterations = query_result_obj.data["iterations"]
			process_jobs = query_result_obj.data["jobs"]
			n_results = len(query_result_obj.results)
			n_next = len(query_result_obj.next)
			#---
			towrite_process =  (source,receive_time,propagation_time,process_time,process_iterations,process_jobs,n_results,n_next)
			## try: 
			the_hop = query_to_hop[query_id]
			while len(data_hops) <= the_hop: data_hops.append(dict())  
			data_hops[query_to_hop[query_id]][query_id] = towrite_process
			## except KeyError:
			## 	data_hops[query_to_hop[query_id]] = { query_id: towrite_process }
			query_data["crossedPeers"].add( source ) 	
			query_data["crossedHosts"].add(  source[0] )
			#----------
			#results
			for result in query_result_obj.results:
				query_data["solutions"].append( result ) 	
			# next
			for nextnode_data in query_result_obj.next:
				nextnode = nextnode_data[0]
				next_query_id = str(nextnode_data[1])
				n_entry_points = len(nextnode_data[2])
				if not query_to_hop.has_key(next_query_id):
					query_to_hop[next_query_id] = query_to_hop[query_id]+1
					query_to_start_propag_time[next_query_id] = receive_time
				propag_info = (query_to_hop[query_id],iteration,source,query_id,receive_time,nextnode,next_query_id,n_entry_points)
				propag_data.append( propag_info )
			# in case no next	
			if len(query_result_obj.next) == 0:
				propag_info = (query_to_hop[query_id],iteration,source,query_id,receive_time,None,None,None)
				propag_data.append( propag_info )
		propag_data.sort()
		for pdat in propag_data:
			hop,itera,src,last_query_id,before_propag_time,dst,next_query_id,n_entry_points = pdat
		query_data["dataHops"] =  data_hops
		query_data["dataPropag"] = propag_data
		query_data["iterations"] = iteration
		return query_data
		


def posnet_point_query(destination,query_name,space_point,source = None,entering_node = None,logger=None):
	""" send a query to a posnet overlay node
	    @param destination: id of the node contacted
	"""
	# Debug
	#####if logger is not None: logger.info("send query to "+str(destination)+" : "+str(query_name))
	#####else: print "send query to",destination
	#-----------
	if source is None: source = (None,None)
	query = posnet_overlay_messages.posnet_semantic_multiquery(source,entering_node,query_name,space_point)
	m = posnet_overlay_messages.posnet_query_message(source,destination,query)
	#print "target for query: ",query.target
	ack_messages = send_query_message(destination,m,logger)
	#pprint(ack_messages)
	return ack_messages

#----------
def posnet_point_query2(destination,cmd,point,logger=None):
	start_query = time.clock()
	host,port = destination
	result_message_gen =  posnet_point_query( (host,port) ,cmd+" (Point query)" ,point)
	query_data = make_query(result_message_gen,logger)	
	end_query = time.clock()
	#----------
	query_data["start_time"] = start_query
	query_data["end_time"] = end_query
	query_data["type"] = cmd
	query_data["parameters"] = point
	query_data["entryPeer"] = (host,port)
	query_data['totalExecutionTime'] = end_query-start_query
	return query_data

def posnet_range_query(destination,query_name,space_point,source = None,entering_node = None,logger=None):
	""" send a query to a posnet overlay node
	    @param destination: id of the node contacted
	"""
	#####if logger is not None: logger.info("send query to "+str(destination)+" : "+str(query_name))
	#####else: print "send query to",destination
	if source is None: source = (None,None)
	query = posnet_overlay_messages.posnet_semantic_multiquery(source,entering_node,query_name,space_point)
	#print "target for query: ",query.target
	m = posnet_overlay_messages.posnet_query_message(source,destination,query)
	ack_messages = send_query_message(destination,m,logger)
	return ack_messages


#----------
def posnet_range_query2(destination,cmd,range_inf,range_sup,logger=None):
	start_query = time.clock()
	host,port = destination
	result_message_gen =  posnet_range_query( (host,port) ,cmd+" (Range query)" ,(range_inf,range_sup) )
	query_data = make_query(result_message_gen,logger)	
	end_query = time.clock()
	#----------
	query_data["start_time"] = start_query
	query_data["end_time"] = end_query
	query_data["type"] = cmd
	query_data["parameters"] = (range_inf,range_sup)
	query_data["entryPeer"] = (host,port)
	query_data['totalExecutionTime'] = end_query-start_query
	return query_data



def posnet_add_random_handle(starting_node,Poset = None,handle=None):
	if Poset is None: Poset = posnet_ping( starting_node)
	Poset_keys = Poset.keys()
	Poset_keys.sort()
	space_point = [random.choice(Poset[y]) for y in Poset_keys]
	if handle is None: handle = ""
	return posnet_add_handle(starting_node,space_point,handle)

def posnet_add_random_handle_range(starting_node,Poset_keys = None,start = None,stop =  None,handle = None,logger= None):
	if Poset_keys is None: Poset_keys = posnet_ping( starting_node).keys()
	Poset_keys.sort()
	space_point = [random.randrange(start,stop) for y in Poset_keys]
	if handle is None: handle = ""
	return posnet_add_handle(starting_node,space_point,handle,logger)



def posnet_add_handle(starting_node,space_point,handle,logger=None):
	if handle is None: handle = ""
	add_handle_message = posnet_overlay_messages.posnet_add_handle(space_point,handle,True)
	message = posnet_overlay_messages.posnet_overlay_add_handle_message(("",0),starting_node,   add_handle_message)
	if logger is not None: logger.info("add point %s"% space_point)
	ack_message = send_tcp_message( starting_node, message,True,True)
	sys.stdout.flush()
	sys.stderr.flush()
	if ack_message is not None: return ack_message.data
	else: return None

def posnet_lock(destination,space_points_and_states):
	""" send a posnet lock message to a posnet overlay node
	    @param destination: id of the destination, this may be (address,port)
	    @param space_points_and_states:  	
	"""
	lockdata = posnet_overlay_messages.posnet_lock(space_points_and_states )
	m   = posnet_overlay_messages.posnet_lock_message( (None,None), destination , lockdata)
	print "lock posnet overlay node",destination
	sys.stdout.flush()
	m.answer_type = 0
	ack_message = send_tcp_message(destination,m,True,True)	
	print "ACK on socket",ack_message.target,"reply from",ack_message.source,":",ack_message
	return ack_message.data

def posnet_unlock(destination,space_points_tab,is_cancel):
	""" send a posnet lock message to a posnet overlay node
	    @param destination: id of the destination, this may be (address,port)
	    @param space_points_tab: table of space points to unlock
	    @param is_cancel: if true indicates that the unlock message is a cancel message
	"""
	lockdata = posnet_overlay_messages.posnet_unlock(space_points_tab,is_cancel)
	m   = posnet_overlay_messages.posnet_unlock_message( (None,None), destination , lockdata)
	print "unlock posnet overlay node",destination
	sys.stdout.flush()
	m.answer_type = 0
	ack_message = send_tcp_message(destination,m,True,True)	
	#print "ACK on socket",ack_message.target,"reply from",ack_message.source,":",ack_message
	#return ack_message.data

#----------------------------------------------
# everything about drawing
def draw_dot(out,dot_data,has_pos = None):
	""" draw a dot (graphivz content). This creates a dot file and the png output file.
	    @param out: the base name for files (dot file will be 'out'.dot, png file will be 'out'.png )
	    @param dot_data: dot data without the global graph encapsulation
	"""
	if has_pos is None: has_pos = False
	f = file( out +".dot","w")
	sp = dot_data.split("\n")
	print >>f,"digraph G {"
	for line in sp:
		if line.find("[label=\"") > -1 and line.find("->") == -1:
			tt = line.split("[label=\"")
			t2 = tt[1].split("\"")
			lab = t2[0]
			if len(lab) < 20: 	
				print >>f,line	
			else:
				print >>f,tt[0]+"[label=\"\""+"\"".join(t2[1:])
		else: print >>f,line
	print >>f,"}"
	f.close()
	cmd = "dot -T png "
	#if has_pos: cmd +=  " -n "
	cmd += " -o "+out+".png "+out+".dot"
	os.system(cmd)
	print >>sys.stderr,"DRAW:",out+".png"
	sys.stderr.flush()
	#os.system("circo -T png -o "+out+"-circo.png "+out+".dot")
	#os.system("neato -T png -o "+out+"-neato.png "+out+".dot")

def compute_top(G_dict):
	top = []
	for node,node_info in G_dict.items():
		is_top = True
		for neigh,rel in node_info.items():
			if rel == "c2p":
				is_top = False
				break
		if not is_top: continue
		top.append(node)
	return top

def compute_pos(G_dict,algo,top = None):
	if top is None: top = compute_top(G_dict)
	pos =dict()
	if len(G_dict) == 0: return pos
	#------------------
	nodelist = sets.Set()
	h  = dict()  
	for node in G_dict.keys(): h[node] = 0	
	sys.stdout.flush()
	for node in top:
		for pred,rel in G_dict[node].items():
			if rel != "p2c": continue
			if pred in top: continue
			h[pred] = 1
			nodelist.add(pred)
	while len(nodelist) > 0:
		#print "nodelist",nodelist
		sys.stdout.flush()
		nodelist2 = sets.Set()  		
		for node in nodelist:
			d = h[node] +1
			for pred,rel in G_dict[node].items():
				if rel != "p2c": continue
				if h[pred] >= d: continue
				h[pred] = d
				nodelist2.add(pred)	
		nodelist = nodelist2
	#------------------
	by_h = dict()
	for node,l in h.items():
		if not by_h.has_key(l): by_h[l] = []
		by_h[l].append(node)	
	lengths = by_h.keys()
	max_n_t = [ len(by_hval) for by_hval in by_h.values()]
	max_n_t.sort()
	max_n = float(max_n_t[-1])
	lengths.sort()
	max_length = lengths[-1]
	for le in lengths:
		xx = 1 
		yy = max_length-le
		nodelist = by_h[le]
		nodelist.sort() 
		for no in nodelist:
			x_position = xx
			y_position = yy
			if algo == 1: pass
			elif algo == 2: x_position =  float(xx)*float(max_n+1)/float(len(nodelist)+1) 
			elif algo == 3: x_position = float(xx)  + 0.1* float(yy)
			elif algo == 4:
				x_position = float(xx)  + 0.1* float(yy+xx)
				y_position = float(yy) + 0.5 * float(xx)
			elif algo == 5: x_position =  float(xx)*float(max_n+1 + 2 * le)/float(len(nodelist)+1)  - float(le)
			pos[no] = [ x_position,y_position]
			xx += 1
	return pos
def posnet_parse_links(fpath):
	ret = dict()
	f = file(fpath,"r")
	line = f.readline()
	while len(line) > 0:
		sp = line[:-1].split("\t")
		if len(sp) < 4: continue
		dim = len(sp)/2 -1
		src = ()
		for z in sp[0:dim]: src += int(z),
		dst = ()
		for z in sp[dim:2*dim]: dst += int(z),
		rel = sp[2*dim]
		rel_sym = sp[2*dim+1]
		ret[( src, dst ) ] = (rel,rel_sym) 
		line = f.readline()
	f.close()
	return ret

def posnet_overlay_topology(starting_node):
	""" """
	#----
	all_nodes = sets.Set()
	visited_nodes = sets.Set()
	all_nodes.add(starting_node) 
	#----
	while len(all_nodes.difference(visited_nodes)) > 0:
		node = random.choice( [x for x in all_nodes.difference(visited_nodes)] )
		host, port = node 	
		towrite = dict()
		#------------
		boot_data = posnet_draw( (host,port),  True )
		visited_nodes.add(node)
		neighbors = boot_data["neighbors"]
		for n in neighbors: all_nodes.add(n)
	return all_nodes



def posnet_export_topology(starting_node,base_dir = None,prefix= None,Poset = None):
	""" """
	complete_graph = dict()
	all_points = sets.Set()
	#----
	if Poset is None: Poset = posnet_ping( starting_node)
	from posnet_semantic_graph import posnet_local_semantic_graph
	sg = posnet_local_semantic_graph(Poset) # used to transform points from list to tuples
	#----
	all_nodes = sets.Set()
	visited_nodes = sets.Set()
	all_nodes.add(starting_node) 
	#----
	graph_data = dict() # used to link semantic nodes from different overlay nodes	a
	#----
	if base_dir is None: base_dir = "."
	if not os.path.exists(base_dir): os.makedirs(base_dir)
	if prefix is None: prefix= ""
	prefix = prefix.split("/")[-1]
	#----
	while len(all_nodes.difference(visited_nodes)) > 0:
		node = random.choice( [x for x in all_nodes.difference(visited_nodes)] )
		host, port = node 	
		towrite = dict()
		#------------
		boot_data = posnet_draw( (host,port),  True )
		visited_nodes.add(node)
		neighbors = boot_data["neighbors"]
		for n in neighbors: all_nodes.add(n)
		ext  = boot_data["ext"]
		mygr = boot_data["graph"]
		#-- 1. verify consistency between neigbors and ext		
		neighbors_from_ext = sets.Set()
		for ext_link in ext:
			label_src,space_point_dst,overlay_node_dst,relation,space_points = ext_link
			neighbors_from_ext.add( overlay_node_dst )
			if not complete_graph.has_key(space_points[0]):  complete_graph[space_points[0]] = dict()
			complete_graph[space_points[0]][space_points[1]] = relation
		neighbors_set = sets.Set()
		for n in neighbors: neighbors_set.add(n)
		diff_set_ext = neighbors_set.difference(neighbors_from_ext)
		diff_ext_set = neighbors_from_ext.difference(neighbors_from_ext)
		if len(diff_set_ext) > 0:
			print node,": in neighbors but not in ext:",diff_set_ext
		if len(diff_ext_set) > 0:
			print node,": in ext but not in neighbors:",diff_ext_set
		for kk,vv in mygr.items():
			tab = []
			all_points.add( kk )
			if not complete_graph.has_key(kk):  complete_graph[kk] = dict()
			for kkk,vvv in vv.items(): complete_graph[kk][kkk] = vvv
	fff= file(os.path.join(base_dir,prefix+"points.tsv"),"w")
	for one_point in all_points:
		print >>fff,"\t".join([str(x) for x in one_point])
	fff.close()
	fff= file(os.path.join(base_dir,prefix+"links.tsv"),"w")
	for src,da in complete_graph.items():
		for dst,rel in da.items():
			rel_sym = rel
			if rel =="c2p": rel_sym = "p2c"
			elif rel == "p2c": rel_sym = "c2p"
			print >>fff,"\t".join([str(x) for x in src])+"\t"+"\t".join([str(x) for x in dst])+"\t"+rel+"\t"+rel_sym
	fff.close()

def posnet_draw_node(starting_node,base_dir = None,prefix= None,Poset = None):
	""" draw node topology. create dot and png files in the output directory specified
	    @param starting_node: the starting point for queries (address,port)
	    @param base_dir: output directory for dot and png files (default: current directory)	
	    @param prefix: output prefix for filename (default: "") 
	"""
	complete_graph = dict()
	all_points = sets.Set()
	#----
	if Poset is None: Poset = posnet_ping( starting_node)
	from posnet_semantic_graph import posnet_local_semantic_graph
	sg = posnet_local_semantic_graph(Poset) # used to transform points from list to tuples
	#----
	all_nodes = sets.Set()
	visited_nodes = sets.Set()
	all_nodes.add(starting_node ) 
	#----
	graph_data = dict() # used to link semantic nodes from different overlay nodes	a
	#----
	if base_dir is None: base_dir = ""
	if not os.path.exists(base_dir): os.makedirs(base_dir)
	if prefix is None: prefix= ""
	prefix = prefix.split("/")[-1]
	#----
	f = cStringIO.StringIO()
	while len(all_nodes.difference(visited_nodes)) > 0:
		node = random.choice( [x for x in all_nodes.difference(visited_nodes)] )
		host, port = node 	
		towrite = dict()
		#------------
		boot_data = posnet_draw( (host,port),  False )
		visited_nodes.add(node)
		picture1 = boot_data["picture"]
		#draw_dot(  os.path.join(base_dir,prefix+"overlay_node_"+str(host)+"_"+str(port)) , picture1)
		print >>f,picture1
		neighbors = boot_data["neighbors"]
		#for n in neighbors: all_nodes.add(n)
		ext  = boot_data["ext"]
		mygr = boot_data["graph"]	
		for kk,vv in mygr.items():
			tab = []
			all_points.add( kk )
			if not complete_graph.has_key(kk):  complete_graph[kk] = vv	
			else:
				for kkk,vvv in vv.items():
					if vvv != "p2p":
						complete_graph[kk][kkk] = vvv
		#------------
		# draw external nodes
		for ext_link in ext:
			label_src,space_point_dst,overlay_node_dst,relation,space_point_src = ext_link
			if not  graph_data.has_key( overlay_node_dst ): graph_data[ overlay_node_dst ] = posnet_graph_request(overlay_node_dst)	
			try:
				myhash = sg.hashable_space_point(space_point_dst)
				vertex_id_dst = graph_data[overlay_node_dst]["vertex_id"][myhash]
				label_dst =   ""+"".join([str(x) for x in space_point_dst])+""
				if relation != 'c2p':
					key =  ( node,overlay_node_dst, relation)
					if towrite.has_key(key): towrite[key] += 1
					else: towrite[key] = 1
				if relation != "p2c" : continue
				print >>f, label_src,"->",label_dst,"[label=\""+relation+"\",color=black,style=bold];"
			except Exception,e: 
				print "EXCEPTION",e,label_src,space_point_dst,overlay_node_dst,relation
				raise
		#draw external links
		for key,number in towrite.items():	
			x,y,relation = key
			x = str(x[0])+"_"+str(x[1])
			y = str(y[0])+"_"+str(y[1])
			#if number != 1:
			#	print >>f2,x,"->",y ,"[label=\""+relation+"("+str(number)+")\",color=black];"
			#else: print >>f2,x,"->",y ,"[label=\""+relation+"\",color=black];"
		#for x in all_nodes:
		#	x = str(x[0])+"_"+str(x[1])
		#	print >>f2,x,";"
	# draw the two topologies
	filename = prefix+"semantic_graph_node"+str(starting_node[0])+"_"+str(starting_node[1])
	draw_dot( os.path.join(base_dir,filename), f.getvalue())
	f.close()
	fff= file(os.path.join(base_dir,prefix+"points_node"+str(starting_node[0])+"_"+str(starting_node[1])+".tsv"),"w")
	for one_point in all_points:
		print >>fff,"\t".join([str(x) for x in one_point])
	fff.close()
	return os.path.join(base_dir,filename+".png")

def posnet_export_topology_local(starting_node,base_dir = None,prefix= None,Poset = None,draw_algorithm = None):
	""" """
	complete_graph = dict()
	all_points = sets.Set()
	#----
	if Poset is None: Poset = posnet_ping( starting_node)
	from posnet_semantic_graph import posnet_local_semantic_graph
	sg = posnet_local_semantic_graph(Poset) # used to transform points from list to tuples
	#----
	all_nodes = sets.Set()
	visited_nodes = sets.Set()
	all_nodes.add(starting_node ) 
	#----
	graph_data = dict() # used to link semantic nodes from different overlay nodes	a
	#----
	if base_dir is None: base_dir = ""
	if not os.path.exists(base_dir): os.makedirs(base_dir)
	if prefix is None: prefix= ""
	prefix = prefix.split("/")[-1]
	#----
	while len(all_nodes.difference(visited_nodes)) > 0:
		node = random.choice( [x for x in all_nodes.difference(visited_nodes)] )
		host, port = node 	
		towrite = dict()
		#------------
		boot_data = posnet_draw( (host,port),  False )
		visited_nodes.add(node)
		neighbors = boot_data["neighbors"]
		for n in neighbors: all_nodes.add(n)
		ext  = boot_data["ext"]
		mygr = boot_data["graph"]	
		for kk,vv in mygr.items():
			tab = []
			all_points.add( kk )
			if not complete_graph.has_key(kk):  complete_graph[kk] = vv	
			else:
				for kkk,vvv in vv.items():
					if vvv != "p2p":
						complete_graph[kk][kkk] = vvv
		#------------
	fff= file(os.path.join(base_dir,prefix+"points.tsv"),"w")
	for one_point in all_points:
		print >>fff,"\t".join([str(x) for x in one_point])
	fff.close()
	

def posnet_draw_topology(starting_node,base_dir = None,prefix= None,Poset = None,draw_algorithm = None):
	""" draw posnet topology. create dot and png files in the output directory specified
	    @param starting_node: the starting point for queries (address,port)
	    @param base_dir: output directory for dot and png files (default: current directory)	
	    @param prefix: output prefix for filename (default: "") 
	"""
	complete_graph = dict()
	all_points = sets.Set()
	#----
	if Poset is None: Poset = posnet_ping( starting_node)
	from posnet_semantic_graph import posnet_local_semantic_graph
	sg = posnet_local_semantic_graph(Poset) # used to transform points from list to tuples
	#----
	all_nodes = sets.Set()
	visited_nodes = sets.Set()
	all_nodes.add(starting_node ) 
	#----
	graph_data = dict() # used to link semantic nodes from different overlay nodes	a
	#----
	if base_dir is None: base_dir = ""
	if not os.path.exists(base_dir): os.makedirs(base_dir)
	if prefix is None: prefix= ""
	prefix = prefix.split("/")[-1]
	#----
	f = cStringIO.StringIO()
	f2 = cStringIO.StringIO()
	while len(all_nodes.difference(visited_nodes)) > 0:
		node = random.choice( [x for x in all_nodes.difference(visited_nodes)] )
		host, port = node 	
		towrite = dict()
		#------------
		boot_data = posnet_draw( (host,port),  False )
		visited_nodes.add(node)
		picture1 = boot_data["picture"]
		#draw_dot(  os.path.join(base_dir,prefix+"overlay_node_"+str(host)+"_"+str(port)) , picture1)
		print >>f,picture1
		neighbors = boot_data["neighbors"]
		for n in neighbors: all_nodes.add(n)
		ext  = boot_data["ext"]
		mygr = boot_data["graph"]	
		for kk,vv in mygr.items():
			tab = []
			all_points.add( kk )
			if not complete_graph.has_key(kk):  complete_graph[kk] = vv	
			else:
				for kkk,vvv in vv.items(): complete_graph[kk][kkk] = vvv
		#------------
		# draw external nodes
		for ext_link in ext:
			label_src,space_point_dst,overlay_node_dst,relation,space_point_src = ext_link
			if not  graph_data.has_key( overlay_node_dst ): graph_data[ overlay_node_dst ] = posnet_graph_request(overlay_node_dst)	
			try:
				myhash = sg.hashable_space_point(space_point_dst)
				vertex_id_dst = graph_data[overlay_node_dst]["vertex_id"][myhash]
				label_dst =   ""+"".join([str(x) for x in space_point_dst])+""
				if relation != 'c2p':
					key =  ( node,overlay_node_dst, relation)
					if towrite.has_key(key): towrite[key] += 1
					else: towrite[key] = 1
				if relation != "p2c" : continue
				print >>f, label_src,"->",label_dst,"[label=\""+relation+"\",color=black,style=bold];"
			except Exception,e: 
				print "EXCEPTION",e,label_src,space_point_dst,overlay_node_dst,relation
				raise
		#draw external links
		def mygetnodeid(s):
			for c in (":",";",".","_"):
				s = s.replace(c,"000")
			return s
		for key,number in towrite.items():	
			x,y,relation = key
			x = str(x[0])+"_"+str(x[1])
			y = str(y[0])+"_"+str(y[1])
			label_edge = relation
			if number != 1: label_edge += "("+str(number)+")"
			print >>f2,mygetnodeid(x),"->",mygetnodeid(y),"[label=\""+label_edge+"\",color=black];"
		for x in all_nodes:
			x = str(x[0])+"_"+str(x[1])
			print >>f2,mygetnodeid(x)," [label=\""+str(x)+"\"];"
	# draw the two topologies		
	draw_dot( os.path.join(base_dir,prefix+"overlay"), f2.getvalue())
	draw_dot( os.path.join(base_dir,prefix+"semantic_graph"), f.getvalue())
	f.close()
	f2.close()
	top = compute_top(complete_graph)
	if draw_algorithm is None: draw_algorithm = 5
	for algo in [draw_algorithm]: #[2,3,4,5]:
		positions  = compute_pos(complete_graph,algo,top)
		f3 = cStringIO.StringIO()
		def elemstr(el,j = None):
			if j is None: j = ""
			return j.join( [str(xx).replace("-","") for xx in el] )
		for element in complete_graph.keys():
			coord = positions[element]
			lab = elemstr(element,"_")
			#print "label",element,lab
			print >>f3,elemstr(element),'[label="'+lab+'", pos="'+str(coord[0])+","+str(coord[1])+'",',
			if element not in top:
				print >>f3,'shape="circle",style=filled',
			else:
				print >>f3,'shape="square",color=green',
			print >>f3,']'
		for el,el_data in complete_graph.items():
			for neig,rel in el_data.items():
				if rel !="p2c": continue
				print >>f3,elemstr(el),"->",elemstr(neig),'[color=black]'
		draw_dot( os.path.join(base_dir,prefix+"semantic_graph_algo"+str(algo)), f3.getvalue(),True)
		f3.close()
	fff= file(os.path.join(base_dir,prefix+"points.tsv"),"w")
	for one_point in all_points:
		print >>fff,"\t".join([str(x) for x in one_point])
	fff.close()
	return all_nodes

if __name__  == "__main__":
	import sys
	host = sys.argv[1] # server address
	port = int(sys.argv[2]) # server port

	mydata = ""
	if len(sys.argv) > 3: mydata = sys.argv[3]
	if mydata == "quit": 
		send_quit_tcp_message(host,port)
	elif mydata in ("bulkdebug","bulk_and_draw","bulk"):
		Poset = posnet_ping( (host,port))
		if mydata == "bulkdebug":
			keys = Poset.keys()
			for k  in  keys:
				Poset[k] = range(1,10)
		nb = int(sys.argv[4])
		for i in xrange(nb): 
			posnet_add_random_handle( (host,port), Poset )
			if mydata == "bulk_and_draw": posnet_draw_topology((host,port),"out/",str(i))
	elif mydata in ("bulkrange"):
		Poset = posnet_ping( (host,port))
		nb = int(sys.argv[4])
		for i in xrange(nb):
			posnet_add_random_handle_range( (host,port), Poset.keys(), 100,100000)
	elif mydata in ("load"):
		fff = file(sys.argv[4],"r")
		line = fff.readline()
		while len(line) > 0:
			sp = [int(y) for y in line[:-1].split("\t")]
			posnet_add_handle( (host,port), sp , '')
			line = fff.readline()
	#--------------------------------------------------------------
	elif mydata == "ping":
		Poset = posnet_ping( (host,port), 0)
		pprint(Poset)
	elif mydata == "ping2":
		Poset = posnet_ping( (host,port), 1)
		pprint(Poset)
	elif mydata == "graph":
		dat = posnet_graph_request(  (host,port), 0 )
		pprint(dat)
	elif mydata == "graph2":
		dat = posnet_graph_request(  (host,port), 1 )
		pprint(dat)
	elif mydata == "state":
		dat = posnet_state_request(  (host,port), 0 )
		pprint(dat)
	elif mydata == "state2":
		dat = posnet_state_request(  (host,port), 1 )
		pprint(dat)
	elif mydata == "dot":
		res = posnet_draw((host,port))
		pprint(res)
	elif mydata == "draw2":
		outdir = "out"
		outname = ""
		if len(sys.argv) > 4: outdir = sys.argv[4]
		if len(sys.argv) > 5: outname = sys.argv[5]
		posnet_draw_node((host,port),outdir+"/",outname)
	elif mydata == "draw":
		outdir = "out"
		outname = ""
		if len(sys.argv) > 4: outdir = sys.argv[4]
		if len(sys.argv) > 5: outname = sys.argv[5]
		posnet_draw_topology((host,port),outdir+"/",outname)
	#-------------------------------------------------------------
	elif mydata == "query":
		Poset = posnet_ping( (host,port), 0)
		point = dict()
		keys = Poset.keys()
		i = 0
		for k  in  keys:
			point[k[-1]] = int( sys.argv[4+i])
			i += 1
		results = posnet_point_query( (host,port), "exact (Point query)", point )
		print "point query result:"
		sys.stdout.flush()
		for result in results:
				print result.data
	elif mydata in ("exact", "all_parents", "all_top", "all_children" ):
		Poset = posnet_ping( (host,port), 0)
		point = dict()
		keys = Poset.keys()
		keys.sort()
		i = 0
		for k  in  keys:
			if len(sys.argv) > 4+i:
				point[k[-1]] = int( sys.argv[4+i])
			else:
				point[k[-1]] = random.randrange(1,10)
			i += 1
		query_name = mydata+" (Point query)"
		print query_name,"(",point,")"
		results = posnet_point_query( (host,port), query_name, point )
		print "result:"
		sys.stdout.flush()
		for result in results:
				print result.data
	elif mydata == "rquery":
		Poset = posnet_ping( (host,port))
		point = dict()
		keys = Poset.keys()
		for k  in  keys:
			point[k[-1]] =  random.randrange(1,10)
		print "point query :",point
		results = posnet_point_query( (host,port), "all_parents (Point query)", point )
		print "point query result:"
		sys.stdout.flush()
		for result in results:
				print result.data

	elif mydata == "parents":
		x = 2
		y = 2
		if len(sys.argv) > 4: x = sys.argv[4]
		if len(sys.argv) > 5: y = sys.argv[5] 
		results = posnet_point_query( (host,port), "all_parents (Point query)", {"x":x,"y":y})
		print "all_parents point query result:"
		sys.stdout.flush()
		for result in results:
				print result.data
	elif mydata == "add":
		x = 2
		y = 2
		if len(sys.argv) > 4: x = int(sys.argv[4])
		if len(sys.argv) > 5: y = int(sys.argv[5] )
		posnet_add_handle( (host,port), [x,y] ,"")
	elif mydata == "add2":
		posnet_add_handle( (host,port), [8,4] ,"")
	elif mydata == "add3":
		posnet_add_handle( (host,port), [4,6] ,"")
	elif mydata == "lock":
		results = posnet_lock( (host,port) , {  (2,2)  : 0 } )
		print "lock results:"
		lock_reply = results
		print lock_reply
	elif mydata == "unlock":
		results = posnet_unlock( (host,port) , [(2,2)] , 1)
		print "unlock results:"
		lock_reply = results
		print lock_reply
	elif mydata == "unlock.cancel":
		results = posnet_unlock( (host,port) , [(2,2)] , 0)
		print "unlock results:"
		lock_reply = results
		print lock_reply
	else:
		raise SystemExit
		#print posnet_point_query( (host,port), "exact (Point query)", {"X":8,"Y":6})			
		#print posnet_point_query( (host,port), "all_top (Point query)", [5,1])			
		#results =  posnet_point_query( (host,port), "all_fit (Point query)", [1,1])			
		#for result in results:
		#	print result.data
		posnet_draw_topology((host,port),"out/",str(0)+"_")
		Poset = posnet_ping( (host,port))
		keys = Poset.keys()
		for k  in  keys:
			Poset[k] = range(1,10)
		for i in xrange(5): 
			posnet_add_random_handle( (host,port), Poset )
			posnet_draw_topology((host,port),"out/",str(i+1)+"_")	
	#---------------------------------------------------

